=begin pod :tag<perl6>

=TITLE Native Calling Interface

=SUBTITLE Call into dynamic libraries that follow the C calling convention

=head1 Getting Started

X<|nativecall>

The simplest imaginable use of NativeCall would look something like this:

    use NativeCall;
    sub some_argless_function() is native('something') { * }
    some_argless_function();

The first line imports various traits and types. The next line looks like
a relatively ordinary Perl 6 sub declaration—with a twist. We use the
"native" trait in order to specify that the sub is actually defined in a
native library. The platform-specific extension (e.g., '.so' or '.dll'),
as well as any customary prefixes (e.g., 'lib') will be added for you.

The first time you call "some_argless_function", the "libsomething" will be
loaded and the "some_argless_function" will be located in it. A call will then
be made. Subsequent calls will be faster, since the symbol handle is retained.

Of course, most functions take arguments or return values—but everything else
that you can do is just adding to this simple pattern of declaring a Perl 6
sub, naming it after the symbol you want to call and marking it with the "native"
trait.

=head1 Changing names

Sometimes you want the name of your Perl subroutine to be different from the name
used in the library you're loading.  Maybe the name is long or has different casing
or is otherwise cumbersome within the context of the module you are trying to
create.

NativeCall provides a "symbol" trait for you to specify the name of the native
routine in your library that may be different from your Perl subroutine name.

=begin code :skip-test
unit module Foo;
use NativeCall;
our sub init() is native('foo') is symbol('FOO_INIT') { * }
=end code

Inside of "libfoo" there is a routine called "FOO_INIT" but, since we're
creating a module called Foo and we'd rather call the routine as C<Foo::init>,
we use the "symbol" trait to specify the name of the symbol in "libfoo"
and call the subroutine whatever we want ("init" in this case).

=head1 Passing and Returning Values

Normal Perl 6 signatures and the C<returns> trait are used in order to convey
the type of arguments a native function expects and what it returns. Here is
an example.

    use NativeCall;
    sub add(int32, int32) returns int32 is native("calculator") { * }

Here, we have declared that the function takes two 32-bit integers and returns
a 32-bit integer. Here are some of the other types that you may pass (this will
likely grow with time).

X<|int8>X<|int16>X<|int32>X<|int64>X<|uint8>X<|uint16>X<|uint32>X<|uint64>X<|long>X<|longlong>X<|ulong>X<|ulonglong>X<|num32>X<|num64>X<|Str>X<|CArray>X<|Pointer>X<|bool>X<|size_t>X<|ssize_t>
=begin table
    int8           (int8_t in C, also used for char)
    int16          (int16_t in C, also used for short)
    int32          (int32_t in C, also used for int)
    int64          (int64_t in C)
    uint8          (uint8_t in C, also used for unsigned char)
    uint16         (uint16_t in C, also used for unsigned short)
    uint32         (uint32_t in C, also used for unsigned int)
    uint64         (uint64_t in C)
    long           (long in C)
    longlong       (long long in C, at least 64-bit)
    ulong          (unsigned long in C)
    ulonglong      (unsigned long long in C, at least 64-bit)
    num32          (float in C)
    num64          (double in C)
    Str            (C string)
    CArray[int32]  (int32_t* in C, an array of 32-bit ints)
    Pointer[void]  (void* in C, can point to all other types)
    bool           (bool from C99)
    size_t         (size_t in C)
    ssize_t        (ssize_t in C)
=end table

Don't use Perl 6 native types like C<int> or C<num>, as they don't have to
correspond to the local C equivalent (e.g., Perl 6's C<int> can be 8 bytes but
C's C<int> is only 4 bytes).

Note that the lack of a C<returns> trait is used to indicate void return type.
Do I<not> use the 'void' type anywhere except in the Pointer parameterization.

For strings, there is an additional "encoded" trait to give some extra hints on
how to do the marshaling.

    use NativeCall;
    sub message_box(Str is encoded('utf8')) is native('gui') { * }

To specify how to marshal string return types, just apply this trait to the
routine itself.

    use NativeCall;
    sub input_box() returns Str is encoded('utf8') is native('gui') { * }

Note that a NULL string pointer can be passed by passing the Str type
object; a NULL return will also be represented by the type object.

If the C function requires the lifetime of a string to exceed the function
call, the argument must be manually encoded and passed as C<CArray[uint8]>:

    use NativeCall;
    # C prototype is void set_foo(const char *)
    sub set_foo(CArray[uint8]) is native('foo') { * }
    # C prototype is void use_foo(void)
    sub use_foo() is native('foo') { * } # will use pointer stored by set_foo()

    my $string = "FOO";
    # The lifetime of this variable must be equal to the required lifetime of
    # the data passed to the C function.
    my $array = CArray[uint8].new($string.encode.list);

    set_foo($array);
    # ...
    use_foo();
    # It's fine if $array goes out of scope starting from here.

=head1 Basic use of Pointers

When the signature of your native function needs a pointer to some native type
(C<int32>, C<uint32>, etc.) all you need to do is declare the argument C<is rw> :

    use NativeCall;
    # C prototype is void my_version(int *major, int *minor)
    sub my_version(int32 is rw, int32 is rw) is native('foo') { * }
    my_version(my int32 $major, my int32 $minor); # Pass a pointer to

Sometimes you need to get a pointer (for example, a library handle) back from a
C library. You don't care about what it points to - you just need to keep hold
of it. The Pointer type provides for this.

    use NativeCall;
    sub Foo_init() returns Pointer is native("foo") { * }
    sub Foo_free(Pointer) is native("foo") { * }

This works out OK, but you may fancy working with a type named something better
than Pointer. It turns out that any class with the representation "CPointer"
can serve this role. This means you can expose libraries that work on handles
by writing a class like this:

=begin code
use NativeCall;

class FooHandle is repr('CPointer') {
    # Here are the actual NativeCall functions.
    sub Foo_init() returns FooHandle is native("foo") { * }
    sub Foo_free(FooHandle) is native("foo") { * }
    sub Foo_query(FooHandle, Str) returns int8 is native("foo") { * }
    sub Foo_close(FooHandle) returns int8 is native("foo") { * }

    # Here are the methods we use to expose it to the outside world.
    method new {
        Foo_init();
    }

    method query(Str $stmt) {
        Foo_query(self, $stmt);
    }

    method close {
        Foo_close(self);
    }

    # Free data when the object is garbage collected.
    submethod DESTROY {
        Foo_free(self);
    }
}
=end code

Note that the CPointer representation can do nothing more than hold a C pointer.
This means that your class cannot have extra attributes. However, for simple
libraries this may be a neat way to expose an object oriented interface to it.

Of course, you can always have an empty class:

    class DoorHandle is repr('CPointer') { }

And just use the class as you would use Pointer, but with potential for
better type safety and more readable code.

Once again, type objects are used to represent NULL pointers.

=head1 Function Pointers

C libraries can expose pointers to C functions as return values of functions and as
members of Structures like, e.g., structs and unions.

Example of invoking a function pointer "$fptr" returned by a function "f", using a
signature defining the desired function parameters and return value:

=begin code :skip-test
sub f() returns Pointer is native('mylib') { * }

my $fptr    = f();
my &newfunc = nativecast(:(Str, size_t --> int32), $fptr);

say newfunc("test", 4);
=end code

=head1 Arrays

NativeCall has some support for arrays. It is constrained to work with machine-size
integers, doubles and strings, sized numeric types, arrays of pointers, arrays of
structs, and arrays of arrays.

Perl 6 arrays, which support amongst other things laziness, are laid out in memory
in a radically different way to C arrays. Therefore, the NativeCall library offers
a much more primitive CArray type, which you must use if working with C arrays.

Here is an example of passing a C array.

=begin code :skip-test
sub RenderBarChart(Str, int32, CArray[Str], CArray[num64]) is native("chart") { * }
my @titles := CArray[Str].new;
@titles[0]  = 'Me';
@titles[1]  = 'You';
@titles[2]  = 'Hagrid';
my @values := CArray[num64].new;
@values[0]  = 59.5e0;
@values[1]  = 61.2e0;
@values[2]  = 180.7e0;
RenderBarChart('Weights (kg)', 3, @titles, @values);
=end code

Note that binding was used to C<@titles>, I<not> assignment! If you assign, you
are putting the values into a Perl 6 array, and it will not work out. If this
all freaks you out, forget you ever knew anything about the C<@> sigil and just
use C<$> all the way when using NativeCall. :-)

    use NativeCall;
    my $titles = CArray[Str].new;
    $titles[0] = 'Me';
    $titles[1] = 'You';
    $titles[2] = 'Hagrid';

Getting return values for arrays works out just the same.

Some library APIs may take an array as a buffer that will be populated by the
C function and, for instance, return the actual number of items populated:

    use NativeCall;
    sub get_n_ints(CArray[int32], int32) returns int32 is native('ints') { * }

In these cases it is important that the CArray has at least the number of
elements that are going to be populated before passing it to the native
subroutine, otherwise the C function may stomp all over Perl's memory
leading to possibly unpredictable behaviour:

=begin code :skip-test
my $ints = CArray[int32].new;
my $number_of_ints = 10;
$ints[$number_of_ints - 1] = 0; # extend the array to 10 items

my $n = get_n_ints($ints, $number_of_ints);
=end code

The memory management of arrays is important to understand. When you create an
array yourself, then you can add elements to it as you wish and it will be
expanded for you as required. However, this may result in it being moved in
memory (assignments to existing elements will never cause this, however). This
means you'd best know what you're doing if you twiddle with an array after passing
it to a C library.

By contrast, when a C library returns an array to you, then the memory can not
be managed by NativeCall, and it doesn't know where the array ends. Presumably,
something in the library API tells you this (for example, you know that when
you see a null element, you should read no further). Note that NativeCall can
offer you no protection whatsoever here - do the wrong thing, and you will get a
segfault or cause memory corruption. This isn't a shortcoming of NativeCall, it's
the way the big bad native world works. Scared? Here, have a hug. Good luck! :-)

=head1 Structs

Thanks to representation polymorphism, it's possible to declare a normal looking
Perl 6 class that, under the hood, stores its attributes in the same way a C
compiler would lay them out in a similar struct definition. All it takes is a
quick use of the "repr" trait:

    class Point is repr('CStruct') {
        has num64 $.x;
        has num64 $.y;
    }

The attributes can only be of the types that NativeCall knows how to marshal into
struct fields. Currently, structs can contain machine-sized integers, doubles,
strings, and other NativeCall objects (CArrays, and those using the CPointer and
CStruct reprs). Other than that, you can do the usual set of things you would with
a class; you could even have some of the attributes come from roles or have them
inherited from another class. Of course, methods are completely fine too. Go wild!

CStruct objects are passed to native functions by reference and native functions
must also return CStruct objects by reference. The memory management
rules for these references are very much like the rules for arrays, though simpler
since a struct is never resized. When you create a struct, the memory is managed for
you and when the variable(s) pointing to the instance of a CStruct go away, the memory
will be freed when the GC gets to it. When a CStruct-based type is used as the return
type of a native function, the memory is not managed for you by the GC.

NativeCall currently doesn't put object members in containers, so assigning new values
to them (with =) doesn't work. Instead, you have to bind new values to the private
members:

=begin code :skip-test
class MyStruct is repr('CStruct') {
    has CArray[num64] $!arr;
    has Str $!str;
    has Point $!point; # Point is a user-defined class

    submethod TWEAK {
        my $arr := CArray[num64].new;
        $arr[0] = 0.9e0;
        $arr[1] = 0.2e0;
        $!arr := $arr;
        $!str := 'Perl 6 is fun';
        $!point := Point.new;
    }
}
=end code

As you may have predicted by now, a NULL pointer is represented by the
type object of the struct type.

=head2 CUnions

Likewise, it is possible to declare a Perl 6 class that stores its
attributes the same way a C compiler would lay them out in a similar
C<union> definition; using the C<CUnion> representation:

=begin code
use NativeCall;

class MyUnion is repr('CUnion') {
    has int32 $.flags32;
    has int64 $.flags64;
}

say nativesizeof(MyUnion.new);  # 8, ie. max(sizeof(MyUnion.flags32), sizeof(MyUnion.flags64))
=end code

=head2 Embedding CStructs and CUnions

CStructs and CUnions can be in turn referenced by—or embedded into—a
surrounding CStruct and CUnion. To say the former we use C<has>
as usual, and to do the latter we use the C<HAS> declarator
instead:

=begin code :skip-test
class MyStruct is repr('CStruct') {
    has Point $.point;  # referenced
    has int32 $.flags;
}

say nativesizeof(MyStruct.new);  # 16, ie. sizeof(struct Point *) + sizeof(int32_t)

class MyStruct2 is repr('CStruct') {
    HAS Point $.point;  # embedded
    has int32 $.flags;
}

say nativesizeof(MyStruct2.new);  # 24, ie. sizeof(struct Point) + sizeof(int32_t)
=end code

=head2 Notes on Memory management

When allocating a struct for use as a struct, make sure that you allocate your
own memory in your C functions. If you're passing a struct into a C function
which needs a C<Str>/C<char*> allocated ahead of time, be sure to assign a
container for a variable of type C<Str> prior to passing your struct into the
function.

=head3 In your Perl6 code...

=begin code :skip-test

class AStringAndAnInt is repr("CStruct") {
  has Str $.a_string;
  has int32 $.an_int32;

  submethod TWEAK {
    $!a_string := Str.new;
    $!an_int32 = 0;
  }

  sub init_struct(AStringAndAnInt is rw, Str, int32) is native('simple-struct') { * }
  method init(:$a_string, :$an_int) {
    init_struct(self, $a_string, $an_int);
  }
}

=end code

In this code we first set up our members, C<$.a_string> and C<$.an_int32>. We then
set the container of C<$.a_string> to a new C<Str>. After that we declare our
C<init_struct()> function for the C<init()> method to wrap around.

=head3 In your C code...

=begin code :lang<C>

typedef struct a_string_and_an_int32_t_ {
  char *a_string;
  int32_t an_int32;
} a_string_and_an_int32_t;

=end code

Here's the structure. Notice how we've got a C<char *> there.

=begin code :lang<C>

void init_struct(a_string_and_an_int32_t *target, char *str, int32_t int32) {
  target->an_int32 = int32;
  target->a_string = strdup(str);

  return;
}

=end code

In this function we initialize the C structure by assigning an integer
by value, and passing the string by reference. The function allocates
memory that it points <char *a_string> to within the structure as it
copies the string.  (Note you will also have to manage deallocation of
the memory as well to avoid memory leaks.)

# A long time ago in a galaxy far, far away...

=begin code :skip-test

my $foo = AStringAndAnInt.new;
$foo.init(a_string => "str", an_int => 123);

=end code

=head1 Typed Pointers

=comment TODO

TBD more

You can type your C<Pointer> by passing the type as a parameter. It works with the native type
but also with C<CArray> and C<CStruct> defined types. NativeCall will not implicitly allocate the memory for it
even when calling new on them.
It's mostly useful in the case of a C routine returning a pointer, or if it's a pointer
embedded in a C<CStruct>.

You have to call C<.deref> on it to access the embedded type.

=begin code :skip-test
my Pointer[int32] $p; #For a pointer on int32;
my Pointer[MyCstruct] $p2 = some_c_routine();
my MyCstruct $mc = $p2.deref;
say $mc.field1;
=end code

It's quite common for a native function to return a pointer to an array of elements. Typed pointers can be dereferenced as an array to obtain individual elements.

=begin code :skip-test
my $n = 5;
# returns a pointer to an array of length $n
my Pointer[Point] $plot = some_other_c_routine($n);
# display the 5 elements in the array
for 1 .. $n -> $i {
    my $x = $plot[$i - 1].x;
    my $y = $plot[$i - 1].y;
    say "$i: ($x, $y)";
}
=end code

Pointers can also be updated to reference successive elements in the array:

=begin code :skip-test
my Pointer[Point] $elem = $plot;
# show differences between successive points
for 1 ..^ $n {
    my Point $lo = $elem.deref;
    ++$elem; # equivalent to $elem = $elem.add(1);
    my Point $hi = (++$elem).deref;
    my $dx = $hi.x = $lo.x;
    my $dy = $hi.y = $lo.y;
    say "$_: delta ($dx, $dy)";
}
=end code

=head1 Buffers and Blobs

=comment TODO

TBD

=head1 Function arguments

NativeCall also supports native functions that take functions as arguments.  One example
of this is using function pointers as callbacks in an event-driven system.  When
binding these functions via NativeCall, one need only provide the equivalent signature
as a constraint on the code parameter:

    use NativeCall;
    # void SetCallback(int (*callback)(const char *))
    my sub SetCallback(&callback (Str --> int32)) is native('mylib') { * }

Note: the native code is responsible for memory management of values passed to
Perl 6 callbacks this way. In other words, NativeCall will not free() strings passed
to callbacks.

=head1 Library Paths and Names

=comment TODO

TBD more

The C<native> trait accepts the library name or the full path.

    use NativeCall;
    constant LIBMYSQL = 'mysqlclient';
    constant LIBFOO = '/usr/lib/libfoo.so.1';
    # and later
    sub mysql_affected_rows returns int32 is native(LIBMYSQL) {*};
    sub bar is native(LIBFOO) {*}

You can also put an incomplete path like './foo' and NativeCall will automatically put
the right extension according to the platform specification.

BE CAREFUL: the C<native> trait and C<constant> are evaluated at compile time. Don't write a constant
that depends on a dynamic variable like:

    # WRONG:
    constant LIBMYSQL = %*ENV<P6LIB_MYSQLCLIENT> || 'mysqlclient';

This will keep the value given at compile time. A module will be precompiled and C<LIBMYSQL> will
keep the value it acquires when the module gets precompiled.

=head2 ABI/API Version

If you write C<native('foo')> NativeCall will search libfoo.so under Unix like system (libfoo.dynlib on OS X, foo.dll on win32).
In most modern system it will require you or the user of your module to install
the development package because it's recommended to always provide an API/ABI version to a
shared library, so libfoo.so ends often being a symbolic link provided only by a development package.

To avoid that, the C<native> trait allows you to specify the API/ABI version. It can be a full
version or just a part of it. (Try to stick to Major version, some BSD code does not care for Minor.)

    use NativeCall;
    sub foo1 is native('foo', v1) {*} # Will try to load libfoo.so.1
    sub foo2 is native('foo', v1.2.3) {*} # Will try to load libfoo.so.1.2.3

    my List $lib = ('foo', 'v1');
    sub foo3 is native($lib) {*}


=head2 Routine

The C<native> trait also accepts a C<Callable> as argument, allowing you to provide your
own way to handle the way it will find the library file to load.

    use NativeCall;
    sub foo is native(sub {'libfoo.so.42'}) {*}

It will only be called at the first invocation of the sub.

=head2 Calling into the standard library

If you want to call a C function that's already loaded, either from the
standard library or from your own program, you can pass the C<Str> type object
as the argument to C<is native>, so C<is native(Str)>.

For example on a UNIX-like operating system, you could use the following code
to print the home directory of the current user:

    use NativeCall;
    my class PwStruct is repr('CStruct') {
        has Str $.pw_name;
        has Str $.pw_passwd;
        has uint32 $.pw_uid;
        has uint32 $.pw_gid;
        has Str $.pw_gecos;
        has Str $.pw_dir;
        has Str $.pw_shell;
    }
    sub getuid()              returns uint32   is native(Str) { * };
    sub getpwuid(uint32 $uid) returns PwStruct is native(Str) { * };

    say getpwuid(getuid()).pw_dir;

Though of course C<$*HOME> is a much easier way :-)


=head1 Exported variables

Variables exported by a library – also named "global" or "extern"
variables – can be accessed using C<cglobal>.  For example:

=for code :skip-test
my $var := cglobal('libc.so.6', 'errno', int32)

This code binds to C<$var> a new L<Proxy|/type/Proxy> object that
redirects all its accesses to the integer variable named "errno" as
exported by the "libc.so.6" library.


=head1 C++ Support

NativeCall offers support to use classes and methods from C++ as shown in
L<https://github.com/rakudo/rakudo/blob/master/t/04-nativecall/13-cpp-mangling.t>
(and its associated C++ file).
Note that at the moment it's not as tested and developed as C support.

=head1 Helper Functions

The C<NativeCall> library exports several subroutines to help you work with
data from native libraries.

=head2 sub nativecast

    sub nativecast($target-type, $source) is export(:DEFAULT)

This will I<cast> the Pointer C<$source> to  an object of C<$target-type>.
The source pointer will typically have been obtained from a call to a native subroutine
that returns a pointer or as a member of a C<struct>, this may be specified as C<void *>
in the C<C> library definition for instance, but you may also cast from a pointer to
a less specific type to a more specific one.

As a special case, if a L<Signature|/type/Signature> is supplied as C<$target-type> then
a C<subroutine> will be returned which will call the native function pointed to by C<$source>
in the same way as a subroutine declared with the C<native> trait.  This is described in
L<Function Pointers|#Function_Pointers>.

=head2 sub cglobal

    sub cglobal($libname, $symbol, $target-type) is export is rw

This returns a L<Proxy|/type/Proxy> object that provides access to the C<extern> named C<$symbol> that
is exposed by the specified library. The library can be specified in the same ways that
they can be to the C<native> trait.

=head2 sub nativesizeof

    sub nativesizeof($obj) is export(:DEFAULT)

This returns the size in bytes of the supplied object, it can be thought of as being
equivalent to C<sizeof> in B<C>.  The object can be a builtin native type such as
C<int64> or C<num64>, a C<CArray> or a class with the C<repr> C<CStruct>, C<CUnion>
or C<CPointer>.

=head1 Examples

Some examples can be found L<in the DBIsh repository
|https://github.com/perl6/DBIish/tree/master/examples>.

=head2 MySQL

You'll need to install MySQL server locally; on Debian-esque systems
it can be installed with something like:

=for code :lang<shell>
sudo apt-get install mysql-server

Prepare your system along these lines before trying out the examples:

=for code :lang<shell>
$ mysql -u root -p
UPDATE mysql.user SET password=password('sa') WHERE user = 'root';
CREATE DATABASE test;

=head2 Microsoft Windows

Here is an example of a Windows API call:

=begin code :method<False>
use NativeCall;

sub MessageBoxA(int32, Str, Str, int32)
    returns int32
    is native('user32')
    { * }

MessageBoxA(0, "We have NativeCall", "ohai", 64);
=end code

=end pod

# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6
